#include "quote_server.h"
#include "json_utils.h"
#include "logger.h"
#include <algorithm>

namespace yquote {

QuoteServer::QuoteServer(int port, const std::string& config_file) 
    : running_(false) {
    
    // 创建配置管理器并加载配置
    config_manager_ = std::make_unique<ConfigManager>();
    loadConfiguration(config_file);
    
    // 从配置文件获取端口号，命令行参数优先
    int websocket_port = port;
    if (port == 8080) { // 如果是默认端口，尝试从配置文件读取
        websocket_port = config_manager_->getInt("server", "websocket_port", 8080);
    }
    
    // 创建组件
    quote_manager_ = std::make_unique<QuoteManager>();
    websocket_server_ = std::make_unique<WebSocketServer>(websocket_port);
    market_simulator_ = std::make_unique<MarketDataSimulator>();
    
    // 应用配置
    applyConfiguration();
    
    // 设置回调函数 - 使用正确的方法名
    market_simulator_->setDataCallback([this](const QuoteData& quote) {
        onQuoteUpdate(quote);
    });
    
    websocket_server_->setMessageCallback([this](const std::string& client_id, const std::string& message) {
        onClientMessage(client_id, message);
    });
    
    websocket_server_->setClientConnectCallback([this](const std::string& client_id) {
        onClientConnect(client_id);
    });
    
    websocket_server_->setClientDisconnectCallback([this](const std::string& client_id) {
        onClientDisconnect(client_id);
    });
}

QuoteServer::~QuoteServer() {
    stop();
}

bool QuoteServer::start() {
    if (running_.load()) {
        return true;
    }
    
    LOG_INFO("正在启动YQuote服务器...");
    
    // 启动WebSocket服务器
    if (!websocket_server_->start()) {
        LOG_ERROR("启动WebSocket服务器失败");
        return false;
    }
    
    // 启动市场数据模拟器 - start()方法返回void，不需要检查返回值
    market_simulator_->start();
    
    running_.store(true);
    LOG_INFO("YQuote服务器启动成功");
    
    return true;
}

void QuoteServer::stop() {
    if (!running_.load()) {
        return;
    }
    
    LOG_INFO("正在停止YQuote服务器...");
    
    running_.store(false);
    
    // 停止组件
    if (market_simulator_) {
        market_simulator_->stop();
    }
    
    if (websocket_server_) {
        websocket_server_->stop();
    }
    
    LOG_INFO("YQuote服务器已停止");
}

bool QuoteServer::isRunning() const {
    return running_.load();
}

void QuoteServer::printStatistics() const {
    LOG_INFO("=== 服务器统计信息 ===");
    LOG_INFO_FMT("服务器状态: %s", (running_.load() ? "运行中" : "已停止"));
    
    if (quote_manager_) {
        auto quotes = quote_manager_->getAllQuotes();
        LOG_INFO_FMT("行情数据数量: %zu", quotes.size());
        LOG_INFO_FMT("订阅关系数量: %zu", quote_manager_->getSubscriptionCount());
    }
    
    if (websocket_server_) {
        auto client_ids = websocket_server_->getClientIds();
        LOG_INFO_FMT("连接客户端数: %zu", client_ids.size());
    }
    
    if (market_simulator_) {
        LOG_INFO_FMT("模拟器状态: %s", (market_simulator_->isRunning() ? "运行中" : "已停止"));
    }
    
    LOG_INFO("========================");
}

void QuoteServer::loadConfiguration(const std::string& config_file) {
    if (!config_manager_->loadConfig(config_file)) {
        LOG_WARN("配置文件加载失败，使用默认配置");
    } else {
        LOG_INFO_FMT("配置文件加载成功: %s", config_file.c_str());
    }
}

void QuoteServer::applyConfiguration() {
    // 应用市场数据配置
    if (market_simulator_) {
        int update_interval = config_manager_->getInt("market_data", "update_interval", 1000);
        market_simulator_->setUpdateInterval(update_interval);
        LOG_DEBUG_FMT("设置市场数据更新间隔: %d ms", update_interval);
        
        double price_volatility = config_manager_->getDouble("market_data", "price_volatility", 2.0);
        market_simulator_->setPriceVolatility(price_volatility);
        LOG_DEBUG_FMT("设置价格波动率: %.2f%%", price_volatility);
        
        // 添加默认股票
        auto default_symbols = config_manager_->getStringList("market_data", "default_symbols");
        if (!default_symbols.empty()) {
            LOG_INFO_FMT("添加默认股票: %zu 只", default_symbols.size());
            for (const auto& symbol : default_symbols) {
                // 为不同市场设置不同的基础价格
                double base_price = 100.0;
                if (symbol.find(".SZ") != std::string::npos || symbol.find(".SH") != std::string::npos) {
                    base_price = 10.0; // A股价格较低
                }
                market_simulator_->addSymbol(symbol, base_price);
            }
        }
    }
    
    LOG_INFO("配置应用完成");
}

void QuoteServer::onQuoteUpdate(const QuoteData& quote) {
    // 更新行情管理器
    quote_manager_->updateQuote(quote);
    
    // 获取订阅该股票的客户端
    auto subscribers = quote_manager_->getSubscribers(quote.symbol);
    
    if (!subscribers.empty()) {
        // 生成JSON消息
        std::string message = JsonUtils::quoteToJson(quote);
        
        // 发送给所有订阅者
        websocket_server_->sendToSubscribers(subscribers, message);
        
        LOG_TRACE_FMT("向 %zu 个客户端发送 %s 行情数据", subscribers.size(), quote.symbol.c_str());
    }
}

void QuoteServer::onClientMessage(const std::string& client_id, const std::string& message) {
    try {
        // 解析消息中的action
        std::string action = JsonUtils::extractStringValue(message, "action");
        
        if (action.empty() && !message.empty()) {
            // 可能是协议层消息，忽略
            return;
        }
        
        LOG_DEBUG_FMT("收到客户端 %s 消息: action=%s", client_id.c_str(), action.c_str());
        
        if (action == "subscribe") {
            processSubscribeMessage(client_id, message);
        } else if (action == "unsubscribe") {
            processUnsubscribeMessage(client_id, message);
        } else if (action == "ping") {
            processPingMessage(client_id);
        } else if (!action.empty()) {
            LOG_WARN_FMT("客户端 %s 发送了不支持的操作: %s", client_id.c_str(), action.c_str());
            sendErrorResponse(client_id, "UNSUPPORTED_ACTION", "不支持的操作: " + action);
        }
        
    } catch (const std::exception& e) {
        LOG_ERROR_FMT("解析客户端 %s 消息失败: %s", client_id.c_str(), e.what());
        sendErrorResponse(client_id, "PARSE_ERROR", "消息解析失败");
    }
}

void QuoteServer::onClientConnect(const std::string& client_id) {
    LOG_INFO_FMT("客户端连接: %s", client_id.c_str());
}

void QuoteServer::onClientDisconnect(const std::string& client_id) {
    LOG_INFO_FMT("客户端断开: %s", client_id.c_str());
    
    // 清理该客户端的所有订阅
    quote_manager_->unsubscribeAll(client_id);
}

void QuoteServer::processSubscribeMessage(const std::string& client_id, const std::string& message) {
    auto symbols = JsonUtils::extractStringArray(message, "symbols");
    
    if (symbols.empty()) {
        LOG_WARN_FMT("客户端 %s 订阅请求中股票代码列表为空", client_id.c_str());
        sendErrorResponse(client_id, "INVALID_SYMBOLS", "股票代码列表为空");
        return;
    }
    
    // 验证股票代码
    std::vector<std::string> valid_symbols;
    std::vector<std::string> supported_symbols = {
        "AAPL", "GOOGL", "MSFT", "AMZN", "TSLA", "META", "NVDA", "NFLX",
        "000001.SZ", "000002.SZ", "600000.SH", "600036.SH"
    };
    
    for (const auto& symbol : symbols) {
        if (std::find(supported_symbols.begin(), supported_symbols.end(), symbol) != supported_symbols.end()) {
            valid_symbols.push_back(symbol);
        } else {
            LOG_WARN_FMT("客户端 %s 请求订阅不支持的股票: %s", client_id.c_str(), symbol.c_str());
        }
    }
    
    if (valid_symbols.empty()) {
        LOG_WARN_FMT("客户端 %s 订阅请求中没有有效的股票代码", client_id.c_str());
        sendErrorResponse(client_id, "NO_VALID_SYMBOLS", "没有有效的股票代码");
        return;
    }
    
    // 添加订阅
    quote_manager_->subscribe(client_id, valid_symbols);
    
    // 发送成功响应
    std::string response = R"({"type":"subscribe_response","status":"success","symbols":[)";
    for (size_t i = 0; i < valid_symbols.size(); ++i) {
        if (i > 0) response += ",";
        response += "\"" + valid_symbols[i] + "\"";
    }
    response += "]}";
    
    websocket_server_->sendMessage(client_id, response);
    
    LOG_INFO_FMT("客户端 %s 订阅了 %zu 只股票", client_id.c_str(), valid_symbols.size());
}

void QuoteServer::processUnsubscribeMessage(const std::string& client_id, const std::string& message) {
    auto symbols = JsonUtils::extractStringArray(message, "symbols");
    
    if (symbols.empty()) {
        // 取消所有订阅
        quote_manager_->unsubscribeAll(client_id);
        symbols = {"all"};
        LOG_INFO_FMT("客户端 %s 取消了所有订阅", client_id.c_str());
    } else {
        // 取消指定股票的订阅
        quote_manager_->unsubscribe(client_id, symbols);
        LOG_INFO_FMT("客户端 %s 取消了 %zu 只股票的订阅", client_id.c_str(), symbols.size());
    }
    
    // 发送成功响应
    std::string response = R"({"type":"unsubscribe_response","status":"success","symbols":[)";
    for (size_t i = 0; i < symbols.size(); ++i) {
        if (i > 0) response += ",";
        response += "\"" + symbols[i] + "\"";
    }
    response += "]}";
    
    websocket_server_->sendMessage(client_id, response);
}

void QuoteServer::processPingMessage(const std::string& client_id) {
    std::string response = R"({"type":"pong","timestamp":")" + std::to_string(std::time(nullptr)) + "\"}";
    websocket_server_->sendMessage(client_id, response);
    LOG_DEBUG_FMT("回复客户端 %s 的ping消息", client_id.c_str());
}

void QuoteServer::sendErrorResponse(const std::string& client_id, const std::string& error_code, const std::string& error_message) {
    std::string response = R"({"type":"error","error_code":")" + error_code + 
                          R"(","error_message":")" + error_message + "\"}";
    websocket_server_->sendMessage(client_id, response);
    LOG_ERROR_FMT("向客户端 %s 发送错误响应: %s - %s", client_id.c_str(), error_code.c_str(), error_message.c_str());
}

} // namespace yquote 